﻿using System;
using System.Data;
using System.Linq;
using ServiceStack.OrmLite.Converters;

namespace ServiceStack.OrmLite.Sqlite.Converters;

public class SqliteGuidConverter : GuidConverter
{
    public override string ColumnDefinition => "CHAR(36)";

    public override string ToQuotedString(Type fieldType, object value)
    {
        var guid = (Guid)value;
        var bytes = guid.ToByteArray();
        var fmt = "x'" + BitConverter.ToString(bytes).Replace("-", "") + "'";
        return fmt;
    }

    public override object GetValue(IDataReader reader, int columnIndex, object[] values)
    {
        if (values != null)
        {
            if (values[columnIndex] == DBNull.Value)
                return null;
        }
        else
        {
            if (reader.IsDBNull(columnIndex))
                return null;
        }

        return reader.GetGuid(columnIndex);
    }
}
    
public class SqliteDataGuidConverter : GuidConverter
{
    public override string ColumnDefinition => "CHAR(36)";

    public override string ToQuotedString(Type fieldType, object value)
    {
        var guid = (Guid)value;
        var bytes = guid.ToByteArray();
        SwapEndian(bytes);
        var p = BitConverter.ToString(bytes).Replace("-","");
        var fmt = "'" + p.Substring(0,8) + "-" 
                  + p.Substring(8,4) + "-" 
                  + p.Substring(12,4) + "-" 
                  + p.Substring(16,4) + "-"
                  + p.Substring(20) + "'";
        return fmt;
    }
        
    public static void SwapEndian(byte[] guid)
    {
        _ = guid ?? throw new ArgumentNullException(nameof(guid));
        Swap(guid, 0, 3);
        Swap(guid, 1, 2);
        Swap(guid, 4, 5);
        Swap(guid, 6, 7);
    }

    private static void Swap(byte[] array, int index1, int index2)
    {
        (array[index1], array[index2]) = (array[index2], array[index1]);
    }        
    public override object GetValue(IDataReader reader, int columnIndex, object[] values)
    {
        if (values != null)
        {
            if (values[columnIndex] == DBNull.Value)
                return null;
        }
        else
        {
            if (reader.IsDBNull(columnIndex))
                return null;
        }

        return reader.GetGuid(columnIndex);
    }
}